﻿using CoreShop.Library;
using CoreShop.Model;
using CoreShop.Model.FromBody;
using CoreShop.PrintService;
using CoreShop.Services;
using FastMember;
using Newtonsoft.Json;
using SqlSugar;
using SqlSugar.Extensions;
using Sunny.UI;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
using Yitter.IdGenerator;
using static CoreShop.Library.GlobalEnumVars;

namespace CoreShop.App
{
    public partial class frmBusinessData : UIForm
    {
        public corecmsfoodordermaster SelectOrderMaster = null;
        public frmBusinessData()
        {
            InitializeComponent();
            this.ShowFullScreen = AppConstVars.showFullScreen;
        }

        private void uiButton1_Click(object sender, System.EventArgs e)
        {
            UIButton btn = (UIButton)sender;
            btn.Selected = true;
        }

        private void FOrders_Shown(object sender, System.EventArgs e)
        {
            BindComboBoxData();
            timer1.Start();
        }

        public void BindComboBoxData()
        {
            try
            {
                #region 
                this.ordertype.Items.Clear();
                var ordertypeList = EnumHelper.EnumToList<GlobalEnumVars.OrderBillType>();
                ordertype.DataSource = ordertypeList;
                ordertype.DisplayMember = "description";
                ordertype.ValueMember = "value";
                if (ordertypeList.Count > 0) this.ordertype.SelectedIndex = 0;
                #endregion
            }
            catch (Exception)
            {
                throw;
            }
        }
        private void timer1_Tick(object sender, System.EventArgs e)
        {
            timer1.Stop();
            //ShowStatusForm(23);
            Thread.Sleep(100);

            layOrderList.Clear();
            LoadOrderList();
        }

        private Expressionable<corecmsfoodordermaster, corecmsuser, sysuser, corecmsfoodorderclass> GetExpressionable()
        {
            int? ordertype = null;
            if (this.ordertype != null) ordertype = CommFunc.ConvertToInt32(this.ordertype.SelectedValue);

            DateTime startDate = CommFunc.ConvertToDateTime(dateTimeRange.DateTimeStar);
            DateTime endDate = CommFunc.ConvertToDateTime(dateTimeRange.DateTimeEnd);
            string str = this.str.Text;

            var where = Expressionable.Create<corecmsfoodordermaster, corecmsuser, sysuser, corecmsfoodorderclass>();

            if (ordertype > 0)
                where = where.And((a, u, su, c) => a.ordertype == ordertype);

            if (startDate != null)
                where = where.And((a, u, su, c) => a.orderDate > startDate);

            if (endDate != null)
                where = where.And((a, u, su, c) => a.orderDate < endDate);

            if (!string.IsNullOrEmpty(str))
            {
                var classModel = new corecmsfoodorderclassServices().AsQueryable().Where(p => p.classNumber == str).First();
                if (classModel != null)
                    where = where.And((a, u, su, c) => a.classId == classModel.id);
                else
                    where = where.And((a, u, su, c) => (a.orderNo.Contains(str) || a.number.Contains(str) || u.mobile.Contains(str) || u.cardNo.Contains(str)));
            }

            return where;
        }


        private void LoadOrderList()
        {
            layOrderList.Clear();
            int count = 0;
            SelectOrderMaster = null;
            //List<corecmsfoodsalemaster> master = new corecmsfoodordermasterServices().SelectByOrdertype(ref count, 1, 200, ordertype, dtStartDate, dtEndDate, str);
            List<corecmsfoodsalemaster> master = new corecmsfoodordermasterServices().SelectByOrdertype(ref count, 1, 200, GetExpressionable());
            this.sum.Text = master.Count.ToString();
            this.amount.Text = master.Sum(p => p.sumAllAmount).ToString();
            int rowId = 1;
            foreach (var item in master)
            {
                OrderItemInfo info = new OrderItemInfo();
                BindOrderItemInfo(info, item);
                UIOrderItem orderItem = new UIOrderItem(info);
                orderItem.Name = GetMenuItemName(item.orderId);
                orderItem.TableClick += Detail_OnClick;
                if (rowId == 1)
                {
                    orderItem.Selected = true;
                    GetSelectOrderMaster(item.orderId);
                    LoadOrderDetail();
                }
                layOrderList.Add(orderItem);
                rowId++;
            }
        }

        private void BindOrderItemInfo(OrderItemInfo info, corecmsfoodsalemaster item)
        {
            info.Tags.Clear();
            info.id = item.orderId;
            info.paymentId = 0;
            info.Name = item.orderNo.ToString();
            string ordertypeName = EnumHelper.GetEnumByValue<GlobalEnumVars.OrderBillType>(item.ordertype.ObjToInt(0));
            info.AddTag(ordertypeName);
            //info1.AddTag("反");
            //info1.Returning = "部分退";
            info.Order = item.orderDate + " " + EnumHelper.GetEnumByValue<GlobalEnumVars.OrderPayStatus>(item.status.ObjToInt(0));
            info.OrderID = "订单尾号:" + item.orderId;
            info.MoneyFrom = item.sumAllAmount.ToString();
        }

        /// <summary>
        /// 刷新绑定单行数据，不必清除再新增控件
        /// </summary>
        /// <param name="orderId"></param>
        private void RefreshOrderRow()
        {
            try
            {
                var mControl = layOrderList.Get(GetMenuItemName(SelectOrderMaster.orderId));
                var menu = (UIOrderItem)mControl;
                OrderItemInfo info = menu.Info;
                string strMaster = JsonConvert.SerializeObject(SelectOrderMaster);
                var orderMaster = JsonConvert.DeserializeObject<corecmsfoodsalemaster>(strMaster);
                BindOrderItemInfo(info, orderMaster);
                layOrderList.Refresh();
            }
            catch (Exception ex)
            {
                UIMessageBox.Show(ex.Message, "系统出错-BindOrdering:", UIStyle.Green, UIMessageBoxButtons.OK);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void GetSelectOrderMaster(long orderId)
        {
            SelectOrderMaster = new corecmsfoodordermasterServices().AsQueryable().Where(p => p.orderId == orderId).First();
        }



        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Detail_OnClick(object sender, System.EventArgs e)
        {
            OrderItemInfo itemInfo = (OrderItemInfo)sender;
            SelectOrderMaster = new corecmsfoodordermasterServices().AsQueryable().Where(p => p.orderId == itemInfo.id).First();
            LoadOrderDetail();
        }

        private void LoadOrderDetail()
        {
            layOrderDetail.Clear();
            if (SelectOrderMaster == null) return;

            List<corecmsfoodorderdetail> orderDetails = new corecmsfoodorderdetailServices().AsQueryable().Where(p => p.orderId == SelectOrderMaster.orderId).ToList();

            btnSettlementUn.Visible = false;
            btnRefund.Visible = false;
            if (SelectOrderMaster.status == (int)GlobalEnumVars.OrderPayStatus.IsPay)
            {
                if (SelectOrderMaster.deskId == 0)
                    btnRefund.Visible = true;
                else btnSettlementUn.Visible = true;
            }

            this.foodInfo.Text = SelectOrderMaster.orderNo + "商品信息";
            this.foodInfoCount.Text = "共" + SelectOrderMaster.sumQuantity + "项：合计￥" + SelectOrderMaster.sumAmount.ToString();

            this.orderNo.Text = SelectOrderMaster.orderNo;
            this.orderDate.Text = SelectOrderMaster.orderDate.ToString();
            this.status.Text = EnumHelper.GetEnumByValue<GlobalEnumVars.OrderPayStatus>(SelectOrderMaster.status.ObjToInt(0));
            this.person.Text = EnumHelper.GetEnumByValue<GlobalEnumVars.OrderBillType>(SelectOrderMaster.ordertype.ObjToInt(0)) + SelectOrderMaster.person + "人就餐";
            this.number.Text = SelectOrderMaster.number.ToString();
            var user = new sysuserServices().AsQueryable().Where(p => p.id == SelectOrderMaster.sysUserId).First();
            if (user != null) this.sysUserName.Text = user.userName;
            var orderPays = new corecmsfoodorderpaymentServices().AsQueryable().Where(p => p.orderId == SelectOrderMaster.orderId).ToList();
            if (orderPays.Count > 0)
            {
                layPayList.Visible = false;
                layPayList.Clear();
                foreach (var item in orderPays)
                {
                    MenuItemInfo info = new MenuItemInfo();
                    info.Name = EnumHelper.GetEnumByValue<GlobalEnumVars.Payment>(item.paymentId);
                    info.Count = "";
                    info.Money = item.payAmount.ToString();
                    UIMenuItem menu = new UIMenuItem(info);
                    menu.SetMinSize();
                    layPayList.Add(menu);
                }
                layPayList.Visible = true;
            }

            decimal sumRealAmount = SelectOrderMaster.sumAmount + SelectOrderMaster.sumTaskAmount + SelectOrderMaster.sumFeedAmount;
            this.sumRealAmount.Text = sumRealAmount.ToString();//商品价格合计
            this.discountAmount.Text = (sumRealAmount - SelectOrderMaster.sumAllAmount - SelectOrderMaster.sumReduceAmount).ToString();//订单金额
            this.sumReduceAmount.Text = SelectOrderMaster.sumReduceAmount.ToString();//顾客应付
            this.sumAllAmount.Text = SelectOrderMaster.sumAllAmount.ToString();//优惠合计
            if (orderDetails.Count > 0)
            {
                layOrderDetail.Visible = false;
                foreach (var item in orderDetails)
                {
                    MenuItemInfo info = new MenuItemInfo();
                    info.Name = item.name;
                    info.Count = item.quantity.ToString();
                    info.Money = item.amount.ToString();
                    info.IsReturning = false;
                    if (item.quantity < 0)
                    {
                        info.IsReturning = true;
                        info.Tags.Add(item.remark);
                    }
                    UIMenuItem menu = new UIMenuItem(info);
                    menu.SetMinSize();
                    layOrderDetail.Add(menu);
                    StatusFormStepIt();
                }
                layOrderDetail.Visible = true;
                HideStatusForm();
            }
        }

        private void btnHomePage_Click(object sender, System.EventArgs e)
        {
            this.Close();
        }

        private void btnPrint_Click(object sender, EventArgs e)
        {
            if (SelectOrderMaster == null)
            {
                UIMessageBox.Show("请选择一个单据后再打印", "提示:", UIStyle.Green, UIMessageBoxButtons.OK);
                return;
            }
            if (!ProcessUtil.GetUserRole(GlobalEnumVars.UserRoleType.isPrintRepair, 0)) return;
            new PrintServices().SetPrintSettlement(SelectOrderMaster);
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private bool SetRefundPayment()
        {
            var where = Expressionable.Create<corecmsfoodorderpayment>();
            where = where.And(p => p.orderId == SelectOrderMaster.orderId);
            where = where.And(p => p.paymentId == (int)GlobalEnumVars.Payment.alipay
            || p.paymentId == (int)GlobalEnumVars.Payment.wechatpay || p.paymentId == (int)GlobalEnumVars.Payment.unionPay);
            var mobilePays = new corecmsfoodorderpaymentServices().AsQueryable().Where(where.ToExpression()).ToList();

            if ((mobilePays != null) && (mobilePays.Count > 0))
            {
                var refundPayTime = AppConstVars.systemsetup.refundPayTime;
                DateTime dPOSTime = SelectOrderMaster.orderDate;
                DateTime dDateNow = DateTime.Now;
                TimeSpan timeSpan = dDateNow - dPOSTime;
                double hPosPayTime = timeSpan.TotalMinutes;
                if ((hPosPayTime < refundPayTime) && (refundPayTime > 0))
                {
                    if (!ShowAskDialog("有移动支付，要原路退款并反结账吗？")) return false;
                    string msg = "";
                    var moblePayment = mobilePays.First();
                    var orderPayment = new OrderPaymentPost()
                    {
                        orderId = moblePayment.orderId.ToString(),
                        payAmount = moblePayment.payAmount
                    };
                    bool bResult = PaymentUtil.SetRefundMobilePay(orderPayment, ref msg);
                    UIMessageBox.Show(msg, "提示:", UIStyle.Green, UIMessageBoxButtons.OK);
                    return bResult;
                }
                else
                {
                    UIMessageBox.Show("有移动支付的单据，必须在规定时间内退单！。", "移动支付退款出错:", UIStyle.Green, UIMessageBoxButtons.OK);
                    return false;
                }
            }
            return SetRefundMemberPay();
        }

        private bool SetRefundMemberPay()
        {
            var userId = CommFunc.ConvertToBigInt(SelectOrderMaster.userId);
            if (userId == 0) return true;
            var member = new corecmsuserServices().GetById(userId);
            if (member == null)
            {
                UIMessageBox.Show("有会员支付，但未找到相应的会员资料！。", "会员支付退款出错:", UIStyle.Green, UIMessageBoxButtons.OK);
                return false;
            }

            var where = Expressionable.Create<corecmsfoodorderpayment>();
            where = where.And(p => p.orderId == SelectOrderMaster.orderId);
            where = where.And(p => p.paymentId == (int)GlobalEnumVars.Payment.balancepay);
            var memberPays = new corecmsfoodorderpaymentServices().AsQueryable().Where(where.ToExpression()).ToList();

            if ((memberPays == null) || (memberPays.Count == 0)) return true;
            var memberPay = memberPays.First();

            var balanceServices = new corecmsuserbalanceServices();
            long sourceId = CommFunc.ConvertToBigInt(memberPay.paymentCode);
            var balance = balanceServices.GetById(sourceId);
            if (balance == null)
            {
                UIMessageBox.Show("未找到要退款的会员支付订单！。", "会员支付退款出错:", UIStyle.Green, UIMessageBoxButtons.OK);
                return false;
            }
            balance.id = CommFunc.GetCorpNextId(AppConstVars.sysUser.corpId, YitIdHelper.NextId());
            balance.orderId = CommonHelper.GetSerialNumberType((int)GlobalEnumVars.SerialNumberType.会员充值消费编号);
            balance.userId = userId;
            balance.type = (int)GlobalEnumVars.UserBalanceTypes.ConsumeRefund;
            balance.storeId = AppConstVars.sysUser.storeId;
            balance.money = -memberPay.payAmount;
            balance.giftAmount = 0;
            balance.balance = 0;
            balance.giftBalance = 0;
            balance.sourceId = sourceId;
            balance.memo = "会员消费退款";
            balance.createTime = DateTime.Now;
            balance.corpId = AppConstVars.sysUser.corpId;
            balance.cardItemId = 0;
            balance.quantity = 0;
            balance.balanceQuantity = 0;
            balance.sysUserId = AppConstVars.sysUser.id;
            balance.paymentId = (int)GlobalEnumVars.Payment.balancepay;
            balance.paymentCode = "";
            balance.payStatus = (int)GlobalEnumVars.OrderPayStatus.UnPay;
            balance.status = (int)GlobalEnumVars.BalanceStatus.UnCheck;

            if (balanceServices.InsertAsync(balance))
            {
                string msg = "";
                //if (new PosRemoteServices(AppConstVars.sUrl).DoRefund(ref balance, ref msg, AppConstVars.sysUser.ccessToken))
                //{
                //    member.balance = balance.balance;
                //    member.giftBalance = balance.giftBalance;
                //    new corecmsuserServices().UpdateAsync(member);
                //    balance.payStatus = (int)GlobalEnumVars.OrderPayStatus.IsPay;
                //    balance.status = (int)GlobalEnumVars.BalanceStatus.SuccessRefund;
                //    balance.paymentTime = DateTime.Now;
                //    balanceServices.UpdateAsync(balance);
                //    balanceServices.Update(a => new corecmsuserbalance()
                //    {
                //        status = (int)GlobalEnumVars.BalanceStatus.IsRefund,
                //    }, a => a.id == sourceId);
                //    return true;
                //}
                //else
                //{
                //    UIMessageBox.Show("会员余额退款失败", "系统提示", UIStyle.Red, UIMessageBoxButtons.OK);
                //    return false;
                //}
            }
            else
            {
                UIMessageBox.Show("会员余额退款失败", "系统提示", UIStyle.Red, UIMessageBoxButtons.OK);
                return false;
            }
            return false;
        }

        private void btnSettlementUn_Click(object sender, EventArgs e)
        {
            #region 判断是否可以反结账
            if (SelectOrderMaster == null)
            {
                UIMessageBox.Show("请选择一个单据后再反结账", "提示:", UIStyle.Green, UIMessageBoxButtons.OK);
                return;
            }
            if (SelectOrderMaster.classId != AppConstVars.classId)
            {
                UIMessageBox.Show("该单据已交班，不能反结账", "提示:", UIStyle.Green, UIMessageBoxButtons.OK);
                return;
            }
            if (SelectOrderMaster.deskId > 0)
            {
                var newOrderMaster = new corecmsfoodorderingmasterServices().AsQueryable().Where(p => p.deskId == SelectOrderMaster.deskId).First();
                if (newOrderMaster != null)
                {
                    UIMessageBox.Show("反结账的单据所属桌台必须是空台状态。", "提示:", UIStyle.Green, UIMessageBoxButtons.OK);
                    return;
                }
            }
            //if (!ProcessUtil.GetUserRole(GlobalEnumVars.UserRoleType.isSettlementUn, 0)) return;
            string msg = "确认要反结账选择的单据吗？";
            if (!ShowAskDialog(msg)) return;

            if (!SetRefundPayment()) return;

            #endregion

            var orderMaster = new corecmsfoodordermasterServices().GetById(SelectOrderMaster.orderId);
            var orderDetail = new corecmsfoodorderdetailServices().AsQueryable().Where(p => p.orderId == SelectOrderMaster.orderId).ToList();
            var orderFeed = new corecmsfoodorderfeedServices().AsQueryable().Where(p => p.orderId == SelectOrderMaster.orderId).ToList();
            var orderTask = new corecmsfoodordertaskServices().AsQueryable().Where(p => p.orderId == SelectOrderMaster.orderId).ToList();
            if ((orderMaster == null) || (orderDetail == null) || (orderDetail.Count == 0))
            {
                UIMessageBox.Show("没有可反结帐的数据。", "结算出错:", UIStyle.Green, UIMessageBoxButtons.OK);
                this.DialogResult = System.Windows.Forms.DialogResult.Cancel;
            }
            string strMaster = JsonConvert.SerializeObject(orderMaster);
            string strDetail = JsonConvert.SerializeObject(orderDetail);
            string strFeed = JsonConvert.SerializeObject(orderFeed);
            string strTask = JsonConvert.SerializeObject(orderTask);
            var orderingMaster = JsonConvert.DeserializeObject<corecmsfoodorderingmaster>(strMaster);
            orderingMaster.status = (int)GlobalEnumVars.TableStatus.TobeSettled;
            var orderingDetail = JsonConvert.DeserializeObject<List<corecmsfoodordering>>(strDetail);
            var orderingFeed = JsonConvert.DeserializeObject<List<corecmsfoodorderingfeed>>(strFeed);
            var orderingTask = JsonConvert.DeserializeObject<List<corecmsfoodorderingtask>>(strTask);

            #region 处理已上传问题，(待改)

            #endregion

            var bl = new corecmsfoodorderingmasterServices().InsertOrUpdate(orderingMaster);
            if (bl)
            {
                bl = new corecmsfoodorderingServices().InsertOrUpdate(orderingDetail);
                new corecmsfoodorderingfeedServices().InsertOrUpdate(orderingFeed);
                new corecmsfoodorderingtaskServices().InsertOrUpdate(orderingTask);
            }
            if (bl)
            {
                new corecmsfoodordermasterServices().DeleteById(orderingMaster.orderId);
                new corecmsfoodorderdetailServices().Delete(p => p.orderId == orderingMaster.orderId);
                new corecmsfoodorderfeedServices().Delete(p => p.orderId == orderingMaster.orderId);
                new corecmsfoodordertaskServices().Delete(p => p.orderId == orderingMaster.orderId);
                new corecmsfoodorderpaymentServices().Delete(p => p.orderId == orderingMaster.orderId);
            }
            if (!bl)
            {
                UIMessageBox.Show("保存数据出错", "保存数据出错:", UIStyle.Green, UIMessageBoxButtons.OK);
                return;
            }

            btnRefresh_Click(btnRefresh, null);
            UIMessageBox.Show("反结账成功", "提示:", UIStyle.Green, UIMessageBoxButtons.OK);
        }

        private string GetMenuItemName(long orderingId)
        {
            return "uiMenuItem_" + orderingId.ToString();
        }


        private void btnRefund_Click(object sender, EventArgs e)
        {
            #region 判断是否可以进行退单
            if (SelectOrderMaster == null)
            {
                UIMessageBox.Show("请选择一个单据进行退单", "提示:", UIStyle.Green, UIMessageBoxButtons.OK);
                return;
            }
            if (SelectOrderMaster.classId != AppConstVars.classId)
            {
                UIMessageBox.Show("该单据已交班，不能退单", "提示:", UIStyle.Green, UIMessageBoxButtons.OK);
                return;
            }
            if (SelectOrderMaster.deskId > 0 && SelectOrderMaster.sourceType == 0)
            {
                UIMessageBox.Show("开台的单据，不能退单。", "提示:", UIStyle.Green, UIMessageBoxButtons.OK);
                return;
            }
            var orderMaster = new corecmsfoodordermasterServices().GetById(SelectOrderMaster.orderId);
            if (orderMaster == null)
            {
                UIMessageBox.Show("没有可退单的数据。", "结算出错:", UIStyle.Green, UIMessageBoxButtons.OK);
                this.DialogResult = System.Windows.Forms.DialogResult.Cancel;
            }
            string msg = "";
            if (orderMaster.status != (int)GlobalEnumVars.OrderPayStatus.IsPay)
            {
                msg = "订单状态为[" + EnumHelper.GetEnumByValue<GlobalEnumVars.OrderPayStatus>(orderMaster.status.ObjToInt(0)) + "]，不能退单。";
                UIMessageBox.Show(msg, "出错:", UIStyle.Green, UIMessageBoxButtons.OK);
                return;
            }
            msg = "确认要对选择的单据进行退单吗？";
            if (!ShowAskDialog(msg)) return;

            if (!SetRefundPayment()) return;

            #endregion
            orderMaster.status = (int)GlobalEnumVars.OrderPayStatus.Refund;
            var bl = new corecmsfoodordermasterServices().InsertOrUpdate(orderMaster);
            if (!bl)
            {
                UIMessageBox.Show("保存数据出错", "保存数据出错:", UIStyle.Green, UIMessageBoxButtons.OK);
                return;
            }
            SelectOrderMaster = orderMaster;
            RefreshOrderRow();
            LoadOrderDetail();
            UIMessageBox.Show("订单退款成功", "提示:", UIStyle.Green, UIMessageBoxButtons.OK);
        }

        private void btnRefresh_Click(object sender, EventArgs e)
        {
            LoadOrderList();
        }

        private void FOrderList_Load(object sender, EventArgs e)
        {

        }

        private void btnPrintLabel_Click(object sender, EventArgs e)
        {
            if (SelectOrderMaster == null)
            {
                UIMessageBox.Show("请选择一个单据后再打印", "提示:", UIStyle.Green, UIMessageBoxButtons.OK);
                return;
            }
            new PrintServices().SetPrintLabel(SelectOrderMaster);
        }
    }
}
